package com.gengzp.ops.service.impl;

import com.gengzp.common.exception.BusinessException;
import com.gengzp.common.model.base.resp.Result;
import com.gengzp.common.utils.RestTemplateUtils;
import com.gengzp.ops.facade.INacosFacadeService;
import com.gengzp.ops.service.IGatewayService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @ClassName GatewayServiceImpl
 * @Description 网关服务层实现
 * @Author gengzp
 * @Date 2025/6/1 19:29
 */
@Service
public class GatewayServiceImpl implements IGatewayService {

    private static final Logger logger = LoggerFactory.getLogger(GatewayServiceImpl.class);

    @Autowired
    private INacosFacadeService INacosFacadeService;

    @Override
    public Result<?> forwardingRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 复制原始请求头
        HttpHeaders requestHeaders = new HttpHeaders();
        Collections.list(request.getHeaderNames()).forEach(h ->
                requestHeaders.addAll(h, Collections.list(request.getHeaders(h)))
        );

        // 请求体
        Object requestBody = null;

        // post请求
        if (StringUtils.equals(request.getMethod(), "POST")) {
            // 参数是 json
            if (StringUtils.equals(request.getContentType(), "application/json")) {
                requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);

                // 参数是 form 表单提交
            } else if (StringUtils.equals(request.getContentType(), "x-www-form-urlencoded")) {
                MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
                request.getParameterMap().forEach((k, v) -> formData.put(k, Arrays.asList(v)));
                requestBody = formData;
            } else {
                // 默认接收json
                requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
            }
        }

        // 请求的实际 requestUri 部分
        String requestUri = request.getRequestURI().replace("/gzp/", "");
        // 截取出服务名的部分
        String service = requestUri.substring(0, requestUri.indexOf("/"));
        // 将url中的服务名部分去掉
         requestUri = requestUri.substring(requestUri.indexOf("/") + 1);

        // 从nacos中查询服务的在线实例地址集合
        List<String> instanceUrls = INacosFacadeService.searchOnlineInstanceUrlByServiceName(service + "-service");
        if (CollectionUtils.isEmpty(instanceUrls)) {
            throw BusinessException.get("服务未找到");
        }

        // 随机取一个实例, 拼接完整的请求url
        String targetUrl = instanceUrls.get(ThreadLocalRandom.current().nextInt(instanceUrls.size()));

        // 发起远程调用
        if ("GET".equalsIgnoreCase(request.getMethod())) {
            return RestTemplateUtils.get(targetUrl, Result.class);
        } else if ("POST".equalsIgnoreCase(request.getMethod())) {
            return RestTemplateUtils.post(
                    String.format("http://%s/%s", targetUrl, requestUri), requestHeaders, requestBody, Result.class);
        } else {
            throw BusinessException.get("不支持的 HTTP 方法：" + request.getMethod());
        }
    }

}
